<template>
  <div class="audit-log-page">
    <!-- 统计卡片 -->
    <div class="stats-cards">
      <div class="stat-card">
        <div class="stat-icon">📊</div>
        <div class="stat-content">
          <div class="stat-label">总日志数</div>
          <div class="stat-value">{{ statistics.total_count }}</div>
        </div>
      </div>
      <div class="stat-card warning">
        <div class="stat-icon">⚠️</div>
        <div class="stat-content">
          <div class="stat-label">未解决</div>
          <div class="stat-value">{{ statistics.unresolved_count }}</div>
        </div>
      </div>
      <div class="stat-card critical">
        <div class="stat-icon">🔥</div>
        <div class="stat-content">
          <div class="stat-label">24小时警告</div>
          <div class="stat-value">{{ statistics.recent_warnings }}</div>
        </div>
      </div>
    </div>

    <!-- 筛选区域 -->
    <div class="filter-section">
      <div class="filter-group">
        <label>日志级别</label>
        <select v-model="filters.level" @change="fetchLogs">
          <option value="">全部</option>
          <option value="info">信息</option>
          <option value="warning">警告</option>
          <option value="error">错误</option>
          <option value="critical">严重</option>
        </select>
      </div>

      <div class="filter-group">
        <label>操作类型</label>
        <select v-model="filters.action" @change="fetchLogs">
          <option value="">全部</option>
          <option value="inspection_warning">巡检警告</option>
          <option value="host_offline">主机离线</option>
          <option value="threshold_exceeded">阈值超出</option>
          <option value="system_alert">系统告警</option>
          <option value="user_action">用户操作</option>
          <option value="dangerous_command">🚨 危险命令</option>
          <option value="sensitive_command">⚠️ 敏感命令</option>
        </select>
      </div>

      <div class="filter-group">
        <label>资源类型</label>
        <select v-model="filters.resource_type" @change="fetchLogs">
          <option value="">全部</option>
          <option value="cpu">CPU</option>
          <option value="memory">内存</option>
          <option value="disk">磁盘</option>
        </select>
      </div>

      <div class="filter-group">
        <label>解决状态</label>
        <select v-model="filters.is_resolved" @change="fetchLogs">
          <option value="">全部</option>
          <option value="false">未解决</option>
          <option value="true">已解决</option>
        </select>
      </div>

      <div class="filter-group">
        <label>搜索</label>
        <input 
          type="text" 
          v-model="searchQuery" 
          @input="handleSearch"
          placeholder="搜索主机名、IP或描述..."
        />
      </div>

      <button @click="refreshLogs" class="btn-refresh">
        🔄 刷新
      </button>
    </div>

    <!-- 批量操作工具栏 -->
    <div v-if="selectedLogs.length > 0" class="bulk-actions-bar">
      <span class="selected-count">已选择 {{ selectedLogs.length }} 条日志</span>
      <div class="action-buttons">
        <button @click="bulkResolve" class="btn btn-success btn-sm">
          ✓ 批量解决
        </button>
        <button @click="bulkDelete" class="btn btn-danger btn-sm">
          🗑️ 批量删除
        </button>
        <button @click="clearSelection" class="btn btn-secondary btn-sm">
          ✕ 取消选择
        </button>
      </div>
    </div>

    <!-- 日志列表 -->
    <div class="logs-container">
      <div class="logs-header">
        <div class="header-left">
          <input 
            type="checkbox" 
            @change="toggleSelectAll" 
            :checked="isAllSelected" 
            class="select-all-checkbox"
          />
          <h3>审计日志列表</h3>
        </div>
        <span class="log-count">共 {{ logs.length }} 条记录</span>
      </div>

      <div v-if="loading" class="loading-state">
        <div class="spinner"></div>
        <p>加载中...</p>
      </div>

      <div v-else-if="logs.length === 0" class="empty-state">
        <div class="empty-icon">📝</div>
        <p>暂无日志记录</p>
      </div>

      <div v-else class="logs-list">
        <div 
          v-for="log in logs" 
          :key="log.id"
          class="log-item"
          :class="[`level-${log.level}`, { resolved: log.is_resolved, selected: isLogSelected(log.id) }]"
        >
          <div class="log-header">
            <div class="log-meta">
              <input 
                type="checkbox" 
                :checked="isLogSelected(log.id)" 
                @change="toggleLogSelection(log.id)"
                class="log-checkbox"
              />
              <span class="log-level" :class="`level-${log.level}`">
                {{ getLevelIcon(log.level) }} {{ log.level_display }}
              </span>
              <span class="log-action">{{ log.action_display }}</span>
              <span class="log-time">{{ formatTime(log.timestamp) }}</span>
            </div>
            <div class="log-actions">
              <button 
                v-if="hasRecording(log)" 
                @click="showReplay(log)"
                class="btn-replay"
                title="查看终端会话回放"
              >
                🎬 查看回放
              </button>
              <button 
                v-if="!log.is_resolved" 
                @click="resolveLog(log.id)"
                class="btn-resolve"
              >
                ✓ 标记已解决
              </button>
              <button @click="deleteLog(log.id)" class="btn-delete">
                🗑️ 删除
              </button>
            </div>
          </div>

          <div class="log-content">
            <h4 class="log-title">{{ log.title }}</h4>
            <p class="log-message">{{ log.message }}</p>

            <div class="log-details">
              <div v-if="log.host_name" class="detail-item">
                <span class="detail-label">主机:</span>
                <span class="detail-value">{{ log.host_name }} ({{ log.host_ip }})</span>
              </div>
              <div v-if="log.resource_type" class="detail-item">
                <span class="detail-label">资源类型:</span>
                <span class="detail-value">{{ log.resource_type.toUpperCase() }}</span>
              </div>
              <div v-if="log.resource_value" class="detail-item">
                <span class="detail-label">使用率:</span>
                <span class="detail-value" :class="{ critical: log.resource_value >= 90 }">
                  {{ log.resource_value.toFixed(2) }}%
                </span>
              </div>
              <div v-if="log.threshold" class="detail-item">
                <span class="detail-label">阈值:</span>
                <span class="detail-value">{{ log.threshold }}%</span>
              </div>
              <div v-if="log.username" class="detail-item">
                <span class="detail-label">操作用户:</span>
                <span class="detail-value">{{ log.username }}</span>
              </div>
            </div>

            <div v-if="log.is_resolved" class="log-resolved">
              <span v-if="log.resolved_by_username">
                ✓ 已由 {{ log.resolved_by_username }} 于 {{ formatTime(log.resolved_at) }} 解决
              </span>
              <span v-else>
                🤖 系统自动解决 (问题已恢复正常) - {{ formatTime(log.resolved_at) }}
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 回放模态框 -->
    <div v-if="replayModal.show" class="replay-modal-overlay" @click="closeReplay">
      <div class="replay-modal" @click.stop>
        <div class="replay-header">
          <h3>🎬 终端会话回放</h3>
          <button @click="closeReplay" class="modal-close">✕</button>
        </div>
        <div class="replay-info">
          <div class="info-item">
            <span class="info-label">主机:</span>
            <span class="info-value">{{ replayModal.log?.host_name }} ({{ replayModal.log?.host_ip }})</span>
          </div>
          <div class="info-item">
            <span class="info-label">用户:</span>
            <span class="info-value">{{ replayModal.log?.username || '未知' }}</span>
          </div>
          <div class="info-item">
            <span class="info-label">命令:</span>
            <span class="info-value command-text">{{ replayModal.command }}</span>
          </div>
          <div class="info-item">
            <span class="info-label">时间:</span>
            <span class="info-value">{{ formatTime(replayModal.log?.timestamp) }}</span>
          </div>
        </div>
        <div class="replay-controls">
          <button @click="toggleReplayPlayback" class="btn-control">
            {{ replayState.isPlaying ? '⏸️ 暂停' : '▶️ 播放' }}
          </button>
          <button @click="resetReplay" class="btn-control">
            🔄 重新播放
          </button>
          <div class="replay-progress">
            <span class="progress-time">{{ formatReplayTime(replayState.currentTime) }}</span>
            <input 
              type="range" 
              v-model="replayState.progress" 
              @input="seekReplay"
              min="0" 
              max="100" 
              class="progress-bar"
            />
            <span class="progress-time">{{ formatReplayTime(replayState.duration) }}</span>
          </div>
          <select v-model="replayState.speed" @change="updateReplaySpeed" class="speed-select">
            <option value="0.5">0.5x</option>
            <option value="1">1x</option>
            <option value="2">2x</option>
            <option value="4">4x</option>
          </select>
        </div>
        <div class="replay-terminal" ref="replayTerminal"></div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import api from '../services/api'
import confirmDialog from '../utils/confirmDialog'
import message from '../utils/message'

const logs = ref([])
const statistics = ref({
  total_count: 0,
  unresolved_count: 0,
  recent_warnings: 0,
  level_stats: [],
  action_stats: [],
  resource_stats: []
})
const loading = ref(false)
const searchQuery = ref('')
const filters = ref({
  level: '',
  action: '',
  resource_type: '',
  is_resolved: ''
})
const selectedLogs = ref([])

// 回放相关状态
const replayModal = ref({
  show: false,
  log: null,
  command: '',
  recording: []
})

const replayState = ref({
  isPlaying: false,
  currentTime: 0,
  duration: 0,
  progress: 0,
  speed: 1,
  currentIndex: 0
})

const replayTerminal = ref(null)
let replayTimer = null
let terminalInstance = null

let searchTimeout = null

// 获取日志列表
const fetchLogs = async () => {
  loading.value = true
  try {
    const params = {
      search: searchQuery.value,
      ...filters.value
    }
    
    // 移除空值
    Object.keys(params).forEach(key => {
      if (params[key] === '') delete params[key]
    })
    
    const response = await api.getAuditLogs(params)
    // 处理分页数据格式
    logs.value = response.results || response || []
  } catch (error) {
    console.error('获取审计日志失败:', error)
    logs.value = []
  } finally {
    loading.value = false
  }
}

// 获取统计信息
const fetchStatistics = async () => {
  try {
    statistics.value = await api.getAuditLogStatistics()
  } catch (error) {
    console.error('获取统计信息失败:', error)
  }
}

// 搜索处理（防抖）
const handleSearch = () => {
  if (searchTimeout) clearTimeout(searchTimeout)
  searchTimeout = setTimeout(() => {
    fetchLogs()
  }, 500)
}

// 刷新日志
const refreshLogs = () => {
  fetchLogs()
  fetchStatistics()
}

// 标记为已解决
const resolveLog = async (id) => {
  const confirmed = await confirmDialog.show({
    title: '标记为已解决',
    message: '确认标记此日志为已解决吗？'
  })
  if (!confirmed) return
  
  try {
    await api.resolveAuditLog(id)
    await fetchLogs()
    await fetchStatistics()
    console.log('已标记为已解决')
  } catch (error) {
    console.error('标记失败:', error)
  }
}

// 删除日志
const deleteLog = async (id) => {
  const confirmed = await confirmDialog.show({
    title: '确认删除',
    message: '确认删除此日志吗？\n此操作不可恢复哦～'
  })
  if (!confirmed) return
  
  try {
    await api.deleteAuditLog(id)
    await fetchLogs()
    await fetchStatistics()
    console.log('删除成功')
  } catch (error) {
    console.error('删除失败:', error)
  }
}

// 获取级别图标
const getLevelIcon = (level) => {
  const icons = {
    info: 'ℹ️',
    warning: '⚠️',
    error: '❌',
    critical: '🚨'
  }
  return icons[level] || '📝'
}

// 格式化时间
const formatTime = (timestamp) => {
  if (!timestamp) return '-'
  const date = new Date(timestamp)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

// 多选功能
const isLogSelected = (id) => selectedLogs.value.includes(id)

const toggleLogSelection = (id) => {
  const index = selectedLogs.value.indexOf(id)
  if (index > -1) {
    selectedLogs.value.splice(index, 1)
  } else {
    selectedLogs.value.push(id)
  }
}

const isAllSelected = computed(() => {
  return logs.value.length > 0 && selectedLogs.value.length === logs.value.length
})

const toggleSelectAll = () => {
  if (isAllSelected.value) {
    selectedLogs.value = []
  } else {
    selectedLogs.value = logs.value.map(log => log.id)
  }
}

const clearSelection = () => {
  selectedLogs.value = []
}

// 批量解决
const bulkResolve = async () => {
  // 只处理未解决的日志
  const unresolvedLogs = selectedLogs.value.filter(id => {
    const log = logs.value.find(l => l.id === id)
    return log && !log.is_resolved
  })
  
  if (unresolvedLogs.length === 0) {
    console.log('所选日志都已解决')
    return
  }
  
  const confirmed = await confirmDialog.show({
    title: '批量标记为已解决',
    message: `确定要标记选中的 ${unresolvedLogs.length} 条未解决日志为已解决吗？`
  })
  if (!confirmed) return
  
  try {
    const result = await api.bulkResolveAuditLogs(unresolvedLogs)
    console.log('批量解决成功:', result.message)
    await fetchLogs()
    await fetchStatistics()
    clearSelection()
  } catch (error) {
    console.error('批量解决失败:', error)
  }
}

// 批量删除
const bulkDelete = async () => {
  const confirmed = await confirmDialog.show({
    title: '批量删除确认',
    message: `确定要删除选中的 ${selectedLogs.value.length} 条日志吗？\n此操作不可恢复哦～`
  })
  if (!confirmed) return
  
  console.log('🚀 开始批量删除，选中的IDs:', selectedLogs.value)
  
  try {
    const result = await api.bulkDeleteAuditLogs(selectedLogs.value)
    console.log('批量删除成功:', result.message)
    await fetchLogs()
    await fetchStatistics()
    clearSelection()
  } catch (error) {
    console.error('❌ 批量删除失败 - 完整错误:', error)
    console.error('❌ 响应数据:', error.response?.data)
    console.error('❌ 状态码:', error.response?.status)
    console.error('❌ 请求URL:', error.config?.url)
    console.error('❌ 请求方法:', error.config?.method)
    
    const statusCode = error.response?.status
    const errorMsg = error.response?.data?.error || error.message
    console.error('批量删除失败:', errorMsg, '状态码:', statusCode)
  }
}

// 检查是否有录制数据
const hasRecording = (log) => {
  return log.extra_data && log.extra_data.has_recording && log.extra_data.session_recording && log.extra_data.session_recording.length > 0
}

// 显示回放
const showReplay = async (log) => {
  const { Terminal } = await import('xterm')
  await import('xterm/css/xterm.css')
  
  replayModal.value = {
    show: true,
    log: log,
    command: log.extra_data?.command || '',
    recording: log.extra_data?.session_recording || []
  }
  
  // 计算总时长
  const recording = replayModal.value.recording
  if (recording.length > 0) {
    replayState.value.duration = recording[recording.length - 1].time
  }
  
  // 等待 DOM 更新后初始化终端
  setTimeout(() => {
    if (replayTerminal.value && !terminalInstance) {
      terminalInstance = new Terminal({
        cursorBlink: false,
        fontSize: 14,
        fontFamily: 'Consolas, Monaco, monospace',
        theme: {
          background: '#0f1923',
          foreground: '#ece8e1'
        },
        cols: 120,
        rows: 30
      })
      terminalInstance.open(replayTerminal.value)
      terminalInstance.writeln('\x1b[36m准备回放...\x1b[0m')
      terminalInstance.writeln('\x1b[90m点击播放按钮开始回放\x1b[0m\r\n')
    }
  }, 100)
}

// 关闭回放
const closeReplay = () => {
  if (replayTimer) {
    clearInterval(replayTimer)
    replayTimer = null
  }
  if (terminalInstance) {
    terminalInstance.dispose()
    terminalInstance = null
  }
  replayModal.value = {
    show: false,
    log: null,
    command: '',
    recording: []
  }
  replayState.value = {
    isPlaying: false,
    currentTime: 0,
    duration: 0,
    progress: 0,
    speed: 1,
    currentIndex: 0
  }
}

// 切换播放/暂停
const toggleReplayPlayback = () => {
  replayState.value.isPlaying = !replayState.value.isPlaying
  
  if (replayState.value.isPlaying) {
    startReplay()
  } else {
    pauseReplay()
  }
}

// 开始回放
const startReplay = () => {
  if (!terminalInstance) return
  
  const recording = replayModal.value.recording
  if (recording.length === 0) return
  
  // 如果是从头开始，清空终端
  if (replayState.value.currentIndex === 0) {
    terminalInstance.clear()
  }
  
  replayTimer = setInterval(() => {
    const index = replayState.value.currentIndex
    
    if (index >= recording.length) {
      // 回放结束
      pauseReplay()
      replayState.value.isPlaying = false
      return
    }
    
    const item = recording[index]
    const nextTime = item.time
    
    // 检查是否到达该项的时间
    if (replayState.value.currentTime >= nextTime) {
      if (item.type === 'output') {
        terminalInstance.write(item.data)
      }
      replayState.value.currentIndex++
    }
    
    // 更新时间和进度
    replayState.value.currentTime += 0.05 * replayState.value.speed
    replayState.value.progress = (replayState.value.currentTime / replayState.value.duration) * 100
    
  }, 50) // 每 50ms 更新一次
}

// 暂停回放
const pauseReplay = () => {
  if (replayTimer) {
    clearInterval(replayTimer)
    replayTimer = null
  }
}

// 重置回放
const resetReplay = () => {
  pauseReplay()
  replayState.value.isPlaying = false
  replayState.value.currentTime = 0
  replayState.value.progress = 0
  replayState.value.currentIndex = 0
  
  if (terminalInstance) {
    terminalInstance.clear()
    terminalInstance.writeln('\x1b[36m准备回放...\x1b[0m')
    terminalInstance.writeln('\x1b[90m点击播放按钮开始回放\x1b[0m\r\n')
  }
}

// 拖动进度条
const seekReplay = () => {
  pauseReplay()
  replayState.value.isPlaying = false
  
  const targetTime = (replayState.value.progress / 100) * replayState.value.duration
  replayState.value.currentTime = targetTime
  
  // 找到对应的索引
  const recording = replayModal.value.recording
  let index = 0
  for (let i = 0; i < recording.length; i++) {
    if (recording[i].time <= targetTime) {
      index = i + 1
    } else {
      break
    }
  }
  replayState.value.currentIndex = index
  
  // 重新渲染到该时间点
  if (terminalInstance) {
    terminalInstance.clear()
    for (let i = 0; i < index; i++) {
      if (recording[i].type === 'output') {
        terminalInstance.write(recording[i].data)
      }
    }
  }
}

// 更新播放速度
const updateReplaySpeed = () => {
  // 如果正在播放，重新开始以应用新速度
  if (replayState.value.isPlaying) {
    pauseReplay()
    startReplay()
  }
}

// 格式化回放时间
const formatReplayTime = (seconds) => {
  const mins = Math.floor(seconds / 60)
  const secs = Math.floor(seconds % 60)
  return `${mins}:${secs.toString().padStart(2, '0')}`
}

onMounted(() => {
  fetchLogs()
  fetchStatistics()
})
</script>

<style scoped>
.audit-log-page {
  padding: 0;
}

/* 统计卡片 */
.stats-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.stat-card {
  background: linear-gradient(135deg, rgba(255, 182, 193, 0.1), rgba(135, 206, 250, 0.1));
  border: 2px solid rgba(255, 182, 193, 0.3);
  border-radius: 12px;
  padding: 20px;
  display: flex;
  align-items: center;
  gap: 15px;
  transition: all 0.3s ease;
}

.stat-card:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 182, 193, 0.6);
  box-shadow: 0 4px 12px rgba(255, 182, 193, 0.2);
}

.stat-card.warning {
  border-color: rgba(255, 193, 7, 0.4);
}

.stat-card.warning:hover {
  border-color: rgba(255, 193, 7, 0.8);
}

.stat-card.critical {
  border-color: rgba(244, 67, 54, 0.4);
}

.stat-card.critical:hover {
  border-color: rgba(244, 67, 54, 0.8);
}

.stat-icon {
  font-size: 36px;
  opacity: 0.9;
}

.stat-content {
  flex: 1;
}

.stat-label {
  font-size: 14px;
  color: var(--color-text-secondary);
  margin-bottom: 5px;
}

.stat-value {
  font-size: 28px;
  font-weight: 700;
  color: var(--color-text-primary);
}

/* 筛选区域 */
.filter-section {
  background: rgba(45, 55, 72, 0.5);
  border: 2px solid rgba(255, 182, 193, 0.3);
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
  align-items: flex-end;
}

.filter-group {
  flex: 1;
  min-width: 150px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.filter-group label {
  font-size: 13px;
  color: var(--color-text-secondary);
  font-weight: 600;
}

.filter-group select,
.filter-group input {
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 182, 193, 0.3);
  border-radius: 6px;
  color: var(--color-text-primary);
  font-size: 14px;
  transition: all 0.3s ease;
}

.filter-group select:focus,
.filter-group input:focus {
  outline: none;
  border-color: rgba(255, 182, 193, 0.6);
  background: rgba(255, 255, 255, 0.08);
}

.btn-refresh {
  padding: 10px 20px;
  background: linear-gradient(135deg, #ff6b9d, #c471ed);
  border: none;
  border-radius: 6px;
  color: white;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  align-self: flex-end;
}

.btn-refresh:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(255, 107, 157, 0.4);
}

/* 日志容器 */
.logs-container {
  background: rgba(45, 55, 72, 0.5);
  border: 2px solid rgba(255, 182, 193, 0.3);
  border-radius: 12px;
  padding: 20px;
}

.logs-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 2px solid rgba(255, 182, 193, 0.3);
}

.logs-header h3 {
  font-size: 18px;
  color: var(--color-text-primary);
  margin: 0;
}

.log-count {
  font-size: 14px;
  color: var(--color-text-secondary);
}

/* 加载和空状态 */
.loading-state,
.empty-state {
  text-align: center;
  padding: 60px 20px;
}

.spinner {
  width: 40px;
  height: 40px;
  margin: 0 auto 20px;
  border: 4px solid rgba(255, 182, 193, 0.3);
  border-top-color: #ff6b9d;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.empty-icon {
  font-size: 64px;
  margin-bottom: 15px;
  opacity: 0.5;
}

.empty-state p {
  color: var(--color-text-secondary);
  font-size: 16px;
}

/* 日志列表 */
.logs-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.log-item {
  background: rgba(255, 255, 255, 0.03);
  border: 2px solid;
  border-radius: 10px;
  padding: 20px;
  transition: all 0.3s ease;
}

.log-item.level-info {
  border-color: rgba(33, 150, 243, 0.4);
}

.log-item.level-warning {
  border-color: rgba(255, 193, 7, 0.4);
}

.log-item.level-error {
  border-color: rgba(244, 67, 54, 0.4);
}

.log-item.level-critical {
  border-color: rgba(156, 39, 176, 0.6);
  background: rgba(156, 39, 176, 0.05);
}

.log-item.resolved {
  opacity: 0.7;
}

.log-item:hover {
  transform: translateX(5px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.log-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.log-meta {
  display: flex;
  gap: 15px;
  align-items: center;
  flex-wrap: wrap;
}

.log-level {
  padding: 4px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
}

.log-level.level-info {
  background: rgba(33, 150, 243, 0.2);
  color: #64b5f6;
}

.log-level.level-warning {
  background: rgba(255, 193, 7, 0.2);
  color: #ffd54f;
}

.log-level.level-error {
  background: rgba(244, 67, 54, 0.2);
  color: #e57373;
}

.log-level.level-critical {
  background: rgba(156, 39, 176, 0.3);
  color: #ba68c8;
}

.log-action {
  font-size: 13px;
  color: var(--color-text-secondary);
  padding: 4px 10px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 4px;
}

.log-time {
  font-size: 12px;
  color: var(--color-text-secondary);
}

.log-actions {
  display: flex;
  gap: 10px;
}

.btn-resolve,
.btn-delete {
  padding: 6px 12px;
  border: none;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-resolve {
  background: linear-gradient(135deg, #4caf50, #66bb6a);
  color: white;
}

.btn-resolve:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(76, 175, 80, 0.4);
}

.btn-delete {
  background: rgba(244, 67, 54, 0.2);
  color: #e57373;
}

.btn-delete:hover {
  background: rgba(244, 67, 54, 0.3);
  transform: translateY(-2px);
}

.log-content {
  margin-top: 15px;
}

.log-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text-primary);
  margin: 0 0 10px 0;
}

.log-message {
  font-size: 14px;
  color: var(--color-text-secondary);
  line-height: 1.6;
  margin: 0 0 15px 0;
}

.log-details {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  padding: 15px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 8px;
  margin-top: 15px;
}

.detail-item {
  display: flex;
  gap: 8px;
  align-items: center;
}

.detail-label {
  font-size: 12px;
  color: var(--color-text-secondary);
  font-weight: 600;
}

.detail-value {
  font-size: 13px;
  color: var(--color-text-primary);
  font-weight: 600;
}

.detail-value.critical {
  color: #e57373;
  font-weight: 700;
}

.log-resolved {
  margin-top: 15px;
  padding: 10px;
  background: rgba(76, 175, 80, 0.1);
  border-left: 3px solid #4caf50;
  border-radius: 4px;
  font-size: 13px;
  color: #81c784;
}

/* 批量操作工具栏 */
.bulk-actions-bar {
  background: linear-gradient(135deg, rgba(255, 107, 157, 0.1), rgba(196, 113, 237, 0.1));
  border: 2px solid rgba(255, 107, 157, 0.4);
  border-radius: 12px;
  padding: 15px 20px;
  margin-bottom: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  animation: slideDown 0.3s ease;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.selected-count {
  font-size: 16px;
  font-weight: 600;
  color: var(--color-text-primary);
}

.action-buttons {
  display: flex;
  gap: 10px;
}

.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-sm {
  padding: 6px 12px;
  font-size: 12px;
}

.btn-success {
  background: linear-gradient(135deg, #4caf50, #66bb6a);
  color: white;
}

.btn-success:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(76, 175, 80, 0.4);
}

.btn-danger {
  background: linear-gradient(135deg, #f44336, #e57373);
  color: white;
}

.btn-danger:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(244, 67, 54, 0.4);
}

.btn-secondary {
  background: rgba(158, 158, 158, 0.3);
  color: var(--color-text-secondary);
}

.btn-secondary:hover {
  background: rgba(158, 158, 158, 0.5);
  transform: translateY(-2px);
}

/* 多选相关 */
.header-left {
  display: flex;
  align-items: center;
  gap: 15px;
}

.select-all-checkbox {
  width: 18px;
  height: 18px;
  cursor: pointer;
  accent-color: #ff6b9d;
}

.log-checkbox {
  width: 18px;
  height: 18px;
  cursor: pointer;
  accent-color: #ff6b9d;
  margin-right: 10px;
}

.log-item.selected {
  background: rgba(255, 107, 157, 0.05);
  border-color: rgba(255, 107, 157, 0.6) !important;
}

.log-item.selected:hover {
  background: rgba(255, 107, 157, 0.08);
}

/* 回放按钮 */
.btn-replay {
  padding: 6px 12px;
  border: none;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  background: linear-gradient(135deg, #9c27b0, #ba68c8);
  color: white;
  transition: all 0.3s ease;
}

.btn-replay:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(156, 39, 176, 0.4);
}

/* 回放模态框 */
.replay-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  animation: fadeIn 0.3s ease;
  backdrop-filter: blur(5px);
}

.replay-modal {
  background: linear-gradient(135deg, rgba(15, 25, 35, 0.98), rgba(20, 30, 45, 0.98));
  border: 2px solid rgba(156, 39, 176, 0.5);
  border-radius: 12px;
  width: 95%;
  max-width: 1400px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 8px 32px rgba(156, 39, 176, 0.3);
  animation: slideUp 0.3s ease;
}

.replay-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  border-bottom: 1px solid rgba(156, 39, 176, 0.3);
}

.replay-header h3 {
  margin: 0;
  color: #ba68c8;
  font-size: 20px;
  font-weight: 700;
}

.modal-close {
  background: transparent;
  border: none;
  color: #8b9aaa;
  font-size: 24px;
  cursor: pointer;
  padding: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  transition: all 0.3s ease;
}

.modal-close:hover {
  background: rgba(255, 70, 85, 0.2);
  color: #ff4655;
  transform: scale(1.1);
}

.replay-info {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 15px;
  padding: 20px 24px;
  background: rgba(0, 0, 0, 0.2);
  border-bottom: 1px solid rgba(156, 39, 176, 0.2);
}

.info-item {
  display: flex;
  gap: 10px;
  align-items: center;
}

.info-label {
  color: #8b9aaa;
  font-size: 13px;
  font-weight: 600;
  min-width: 60px;
}

.info-value {
  color: #ece8e1;
  font-size: 13px;
  flex: 1;
}

.info-value.command-text {
  font-family: 'Consolas', 'Monaco', monospace;
  color: #ba68c8;
  font-weight: 600;
}

.replay-controls {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 15px 24px;
  background: rgba(0, 0, 0, 0.3);
  border-bottom: 1px solid rgba(156, 39, 176, 0.2);
}

.btn-control {
  padding: 8px 16px;
  background: linear-gradient(135deg, #9c27b0, #ba68c8);
  border: none;
  border-radius: 8px;
  color: white;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  white-space: nowrap;
}

.btn-control:hover {
  background: linear-gradient(135deg, #7b1fa2, #9c27b0);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(156, 39, 176, 0.4);
}

.replay-progress {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
}

.progress-time {
  font-size: 12px;
  color: #8b9aaa;
  font-family: 'Consolas', 'Monaco', monospace;
  min-width: 40px;
}

.progress-bar {
  flex: 1;
  height: 6px;
  -webkit-appearance: none;
  appearance: none;
  background: rgba(139, 154, 170, 0.3);
  border-radius: 3px;
  outline: none;
  cursor: pointer;
}

.progress-bar::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ba68c8;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(186, 104, 200, 0.5);
  transition: all 0.3s ease;
}

.progress-bar::-webkit-slider-thumb:hover {
  transform: scale(1.2);
  box-shadow: 0 2px 12px rgba(186, 104, 200, 0.8);
}

.progress-bar::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ba68c8;
  cursor: pointer;
  border: none;
  box-shadow: 0 2px 8px rgba(186, 104, 200, 0.5);
}

.speed-select {
  padding: 6px 12px;
  background: rgba(30, 40, 55, 0.8);
  border: 1.5px solid rgba(156, 39, 176, 0.3);
  border-radius: 6px;
  color: #ece8e1;
  font-size: 13px;
  cursor: pointer;
  outline: none;
  transition: all 0.3s ease;
}

.speed-select:hover {
  border-color: #ba68c8;
}

.replay-terminal {
  flex: 1;
  padding: 15px;
  overflow: hidden;
  background: #0f1923;
}

.replay-terminal :deep(.xterm) {
  height: 100%;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(30px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
</style>
